package com.zrwl.poscloud.xo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zrwl.poscloud.base.entity.User;
import com.zrwl.poscloud.base.entity.UserEmployeeR;
import com.zrwl.poscloud.base.enums.EStatus;
import com.zrwl.poscloud.base.global.BaseSQLConf;
import com.zrwl.poscloud.base.global.Constants;
import com.zrwl.poscloud.base.global.ErrorCode;
import com.zrwl.poscloud.base.superI.SuperServiceImpl;
import com.zrwl.poscloud.commons.config.jwt.Audience;
import com.zrwl.poscloud.commons.config.jwt.JwtTokenUtil;
import com.zrwl.poscloud.commons.exception.exceptionType.InsertException;
import com.zrwl.poscloud.commons.holder.RequestHolder;
import com.zrwl.poscloud.commons.utils.*;
import com.zrwl.poscloud.xo.global.MessageConf;
import com.zrwl.poscloud.xo.global.RedisConf;
import com.zrwl.poscloud.xo.global.SQLConf;
import com.zrwl.poscloud.xo.global.SysConf;
import com.zrwl.poscloud.xo.mapper.UserMapper;
import com.zrwl.poscloud.xo.service.SysParamsService;
import com.zrwl.poscloud.xo.service.UserEmployeeRService;
import com.zrwl.poscloud.xo.service.UserService;
import com.zrwl.poscloud.xo.utils.WebUtil;
import com.zrwl.poscloud.xo.vo.UserEmployeeRVO;
import com.zrwl.poscloud.xo.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 用户信息 服务实现类
 *
 * @author 刘思童 AutoGenerate
 * @date 2021-02-24
 */
@Service
public class UserServiceImpl extends SuperServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    WebUtil webUtil;
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private SysParamsService sysParamsService;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private UserMapper userMapper;
    @Value(value = "${tokenHead}")
    private String tokenHead;
    /**
     * token过期的时间
     */
    @Value(value = "${audience.expiresSecond}")
    private Long expiresSecond;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private Audience audience;
    @Autowired
    private UserEmployeeRService userEmployeeRService;

    @Override
    public User insertUserInfo(HttpServletRequest request, String response) {
        Map<String, Object> map = JsonUtils.jsonToMap(response);
        boolean exist = false;
        User user = new User();
        Map<String, Object> data = JsonUtils.jsonToMap(JsonUtils.objectToJson(map.get(SysConf.DATA)));
        if (data.get(SysConf.UUID) != null && data.get(SysConf.SOURCE) != null) {
            if (getUserBySourceAnduuid(data.get(SysConf.SOURCE).toString(), data.get(SysConf.UUID).toString()) != null) {
                user = getUserBySourceAnduuid(data.get(SysConf.SOURCE).toString(), data.get(SysConf.UUID).toString());
                exist = true;
            }
        } else {
            log.error("未获取到uuid或source");
            throw new InsertException(ErrorCode.INSERT_DEFAULT_ERROR, MessageConf.INSERT_DEFAULT_ERROR);
        }

        if (data.get(SysConf.EMAIL) != null) {
            user.setEmail(data.get(SysConf.EMAIL).toString());
        }
        if (data.get(SysConf.AVATAR) != null) {
            user.setAvatar(data.get(SysConf.AVATAR).toString());
        }
        if (data.get(SysConf.NICKNAME) != null) {
            user.setNickName(data.get(SysConf.NICKNAME).toString());
        }
        user.setLoginCount(user.getLoginCount() + 1);
        user.setLastLoginTime(new Date());
        user.setLastLoginIp(IpUtils.getIpAddr(request));
        if (exist) {
            user.updateById();
        } else {
            user.setUuid(data.get(SysConf.UUID).toString());
            user.setSource(data.get(SysConf.SOURCE).toString());
            user.setUserName("mg".concat(user.getSource()).concat(user.getUuid()));
            //产生(0,999999]之间的随机数
            Integer randNum = (int) (Math.random() * (999999) + 1);
            //进行六位数补全
            String workPassWord = String.format("%06d", randNum);
            user.setPassWord(workPassWord);
            user.insert();
        }
        return user;
    }

    @Override
    public User getUserBySourceAnduuid(String source, String uuid) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(BaseSQLConf.UUID, uuid).eq(BaseSQLConf.SOURCE, source);
        return userService.getOne(queryWrapper);
    }

    @Override
    public Integer getUserCount(int status) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(BaseSQLConf.STATUS, status);
        return userService.count(queryWrapper);
    }

    @Override
    public User serRequestInfo(User user) {
        HttpServletRequest request = RequestHolder.getRequest();
        Map<String, String> map = IpUtils.getOsAndBrowserInfo(request);
        String os = map.get("OS");
        String browser = map.get("BROWSER");
        String ip = IpUtils.getIpAddr(request);
        user.setLastLoginIp(ip);
        user.setOs(os);
        user.setBrowser(browser);
        user.setLastLoginTime(new Date());
        //从Redis中获取IP来源
        String jsonResult = stringRedisTemplate.opsForValue().get(RedisConf.IP_SOURCE + Constants.SYMBOL_COLON + ip);
        if (StringUtils.isEmpty(jsonResult)) {
            String addresses = IpUtils.getAddresses(SysConf.IP + Constants.SYMBOL_RIGHT_EQUAL + ip, "utf-8");
            if (StringUtils.isNotEmpty(addresses)) {
                user.setIpSource(addresses);
                stringRedisTemplate.opsForValue().set(RedisConf.IP_SOURCE + Constants.SYMBOL_COLON + ip, addresses, 24, TimeUnit.HOURS);
            }
        } else {
            user.setIpSource(jsonResult);
        }
        return user;
    }

    @Override
    public List<User> getUserListByIds(List<String> ids) {
        List<User> userList = new ArrayList<>();
        if (ids == null || ids.size() == 0) {
            return userList;
        }
        Collection<User> userCollection = userService.listByIds(ids);
        userCollection.forEach(item -> {
            userList.add(item);
        });
        return userList;
    }

    @Override
    public User getUserByMobile(String mobile) {
        User userMobile = userMapper.getUserMobile(mobile);
        return userMobile;
    }

    @Override
    public UserVO getUserWeChat(String weChat) {
        UserVO userWeChat = userMapper.getUserWeChat(weChat);
        return userWeChat;
    }

    @Override
    public IPage<User> getPageList(UserVO userVO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 查询用户名
        if (StringUtils.isNotEmpty(userVO.getKeyword()) && !StringUtils.isEmpty(userVO.getKeyword().trim())) {
            queryWrapper.and(
                    wrapper -> wrapper.like(SQLConf.USER_NAME, userVO.getKeyword().trim())
                            .or().like(SQLConf.NICK_NAME, userVO.getKeyword().trim())
                            .or().eq("mobile", userVO.getKeyword().trim())
            );
        }
        if (StringUtils.isNotEmpty(userVO.getSource()) && !StringUtils.isEmpty(userVO.getSource().trim())) {
            queryWrapper.eq(SQLConf.SOURCE, userVO.getSource().trim());
        }
        queryWrapper.select(User.class, i -> !i.getProperty().equals(SQLConf.PASS_WORD));
        Page<User> page = new Page<>();
        page.setCurrent(userVO.getCurrentPage());
        page.setSize(userVO.getPageSize());
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        IPage<User> pageList = userService.page(page, queryWrapper);
        List<User> list = pageList.getRecords();
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public List<User> getAllList(UserVO userVO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByAsc(SQLConf.CREATE_TIME);
        List<User> list = userService.list(queryWrapper);
        return list;
    }

    @Override
    public String add(UserVO userVO) {
        User entity = new User();
        BeanUtils.copyProperties(userVO, entity, SysConf.STATUS);
        userVO.setStatus(entity.getStatus());
        String defaultPassword = sysParamsService.getSysParamsValueByKey(SysConf.SYS_DEFAULT_PASSWORD);
        entity.setPassWord(MD5Utils.string2MD5(defaultPassword));
        entity.setSource("regedit");
        entity.insert();
        userVO.setUid(entity.getUid());
        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    @Override
    public String edit(UserVO userVO) {
        User entity = userService.getById(userVO.getUid());
        BeanUtils.copyProperties(userVO, entity);
        //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
        entity.updateById();
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String delete(UserVO userVO) {
        User entity = userService.getById(userVO.getUid());
        entity.setStatus(EStatus.DISABLED);
        //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
        entity.updateById();
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String resetUserPassword(UserVO userVO) {
        String defaultPassword = sysParamsService.getSysParamsValueByKey(SysConf.SYS_DEFAULT_PASSWORD);
        User user = userService.getById(userVO.getUid());
        user.setPassWord(MD5Utils.string2MD5(defaultPassword));
//        user.setUpdateTime(new Date());
        user.updateById();
        return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
    }

    @Override
    public String getPresentUserUid() {
        HttpServletRequest request = RequestHolder.getRequest();
        if (request.getAttribute(SysConf.ADMIN_UID) == null || request.getAttribute(SysConf.ADMIN_UID) == "") {
            return null;
        } else {
            return request.getAttribute(SysConf.ADMIN_UID).toString();
        }
    }

    @Override
    public UserVO getMe() {
        UserVO userVO;
        HttpServletRequest request = RequestHolder.getRequest();
        if (request.getAttribute("cloudRequest") != null && !request.getAttribute("cloudRequest").equals("")) {
            userVO = (UserVO) JsonUtils.jsonToObject(redisUtil.get(RedisConf.MOBILE_LOGIN_TOKEN_KEY + RedisConf.SEGMENTATION + request.getAttribute("cloudRequest")), UserVO.class);
        } else {
            if (request.getAttribute(SysConf.ADMIN_UID) == null || request.getAttribute(SysConf.ADMIN_UID) == "") {
                return new UserVO();
            }
            String oldTokenUid = request.getAttribute(SysConf.TOKEN).toString();
            String token = redisUtil.get(RedisConf.LOGIN_UUID_KEY + RedisConf.SEGMENTATION + oldTokenUid.substring(tokenHead.length()));
            String redisStr = redisUtil.get(RedisConf.MOBILE_LOGIN_TOKEN_KEY + RedisConf.SEGMENTATION + token);
            userVO = (UserVO) JsonUtils.jsonToObject(redisStr, UserVO.class);
            if (userVO == null) {
                User user = userService.getById(request.getAttribute(SysConf.ADMIN_UID).toString());
                if (user != null) {
                    user.setPassWord(null);
                    userVO = new UserVO();
                    BeanUtils.copyProperties(user, userVO);
                    String redisStrEmployee = redisUtil.get(RedisConf.EMPLOYEE_INFO + RedisConf.SEGMENTATION + userVO.getUid());
                    UserEmployeeRVO userEmployeeRVO = (UserEmployeeRVO) JsonUtils.jsonToObject(redisStrEmployee, UserEmployeeRVO.class);
                    if (userEmployeeRVO == null) {
                        userEmployeeRVO = new UserEmployeeRVO();
                        UserEmployeeR defaultUserEmployeeR = userEmployeeRService.getDefaultUserEmployeeRMes(user.getUid());
                        if (defaultUserEmployeeR != null) {
                            BeanUtils.copyProperties(defaultUserEmployeeR, userEmployeeRVO);
                        }
                    }
                    userVO.setUserEmployeeRVO(userEmployeeRVO);
                } else {
                    userVO = new UserVO();
                }
                // 私钥
                String base64Secret = audience.getBase64Secret();
                String tokenUid = StringUtils.getUUID();
                String newToken = tokenHead + jwtTokenUtil.refreshToken(token, base64Secret, expiresSecond * 1000);
                redisUtil.delete(RedisConf.MOBILE_LOGIN_TOKEN_KEY + Constants.SYMBOL_COLON + token);
                redisUtil.delete(RedisConf.LOGIN_UUID_KEY + Constants.SYMBOL_COLON + oldTokenUid.substring(tokenHead.length()));
                redisUtil.setEx(RedisConf.MOBILE_LOGIN_TOKEN_KEY + Constants.SYMBOL_COLON + newToken, JsonUtils.objectToJson(userVO), expiresSecond, TimeUnit.SECONDS);
                redisUtil.setEx(RedisConf.LOGIN_UUID_KEY + Constants.SYMBOL_COLON + tokenUid, newToken, expiresSecond, TimeUnit.SECONDS);
            } else {
                if (userVO.getEmployeeInfo() == null) {
                    String redisStrEmployee = redisUtil.get(RedisConf.EMPLOYEE_INFO + RedisConf.SEGMENTATION + userVO.getUid());
                    UserEmployeeRVO userEmployeeRVO = (UserEmployeeRVO) JsonUtils.jsonToObject(redisStrEmployee, UserEmployeeRVO.class);
                    if (userEmployeeRVO == null) {
                        userEmployeeRVO = new UserEmployeeRVO();
                        UserEmployeeR defaultUserEmployeeR = userEmployeeRService.getDefaultUserEmployeeRMes(userVO.getUid());
                        if (defaultUserEmployeeR != null) {
                            BeanUtils.copyProperties(defaultUserEmployeeR, userEmployeeRVO);
                        }
                    }
                    userVO.setUserEmployeeRVO(userEmployeeRVO);
                }
            }
        }
        return userVO;
    }

    @Override
    public void setMe(UserVO userVO) {
        HttpServletRequest request = RequestHolder.getRequest();
        String tokenUid = request.getAttribute(SysConf.TOKEN).toString();
        String token = redisUtil.get(RedisConf.LOGIN_UUID_KEY + RedisConf.SEGMENTATION + tokenUid.substring(tokenHead.length()));
        redisUtil.setEx(RedisConf.MOBILE_LOGIN_TOKEN_KEY + Constants.SYMBOL_COLON + token, JsonUtils.objectToJson(userVO), expiresSecond, TimeUnit.SECONDS);
    }
    //
    @Override
    public UserVO getBuild(UserVO userVO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("we_chat",userVO.getWeChat());
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByAsc(SQLConf.CREATE_TIME);
        queryWrapper.last("limit 1");
        User user = userService.getOne(queryWrapper);
        if(user == null){
            add(userVO);
        }else {
            userVO.setUid(user.getUid());
        }
        return userVO;
    }

    @Override
    public List<UserVO> getUserMesByNickNameAndUserNameOrMobile(UserVO userVO) {
        return userMapper.getUserMesByNickNameAndUserNameOrMobile(userVO);
    }

    /**
     * 获取用户信息
     *
     * @param userUid 用户uid
     * @return 用户信息
     */
    @Override
    public List<UserVO> getUserInfo(String userUid) {
        return userMapper.getUserInfo(userUid);
    }

    @Override
    public void setMe(String token, UserVO userVO) {
        redisUtil.setEx(RedisConf.EMPLOYEE_INFO + RedisConf.SEGMENTATION + userVO.getUid(), JsonUtils.objectToJson(userVO.getUserEmployeeRVO()), expiresSecond, TimeUnit.SECONDS);
        redisUtil.setEx(RedisConf.MOBILE_LOGIN_TOKEN_KEY + Constants.SYMBOL_COLON + token, JsonUtils.objectToJson(userVO), expiresSecond, TimeUnit.SECONDS);
    }
}
